var tabs=null;
var curEvent=null;
var curContact=null;
var calService = null;
var conService = null;
var groupEntries = null;
var contactEntries = null;
var calendarEntries = null;


function initGData() {
	if (!calService) {
		calService = new google.gdata.calendar.CalendarService('Atendimentos');
		calService.useOAuth('google');
	}
	if (!conService){
		conService = new google.gdata.contacts.ContactsService('ContactSearch');
		conService.useOAuth('google');
	}
}

function isContactGroupEnabled(entry)
{
	for(var i in entry.gContact$groupMembershipInfo){
		var contactGroupId=entry.gContact$groupMembershipInfo[i].href;		
		for(var j in groupEntries){
			if (groupEntries[j].id.$t==contactGroupId){
				var checked = getExtendedProperty(groupEntries[j],'checked') || ''; 				
				return (checked=='checked');
			}
		}
	}
	return true;
}

function filterContacts(chrs,callback)
{
	var items = [];
	var entry = null;
	var pattern = new RegExp('\\b'+chrs,"i");
	for (var i = 0; i<contactEntries.length; i++) {
		entry = contactEntries[i];
		if (isContactGroupEnabled(entry)){
			var id = entry.id.$t;
			var name = entry.title.$t;
			if (name.search(pattern)>=0){
				name = properCase(name);
				var autosugestItem = {
					'id'    : id,
					'info'  : '',
					'value' : name,
					'seq'   : i
				};
				items.push(autosugestItem);					
			}
		}
	}
	items.sort(function(a,b){
		return (a.value==b.value)?0:(a.value>b.value?1:-1);
	});
	var response={
		status:'OK',
		data: {
			results: items
		}
	};
	callback(response);
};

function setupInputSearch(inputId, onSelectCallback)
{
	var target = $('#'+inputId);
	if(!target)
		return;	
	var autoSuggest = new AutoSuggest(
		inputId,
		{
			varname:"input",
			json:true,
			noresults: "New",
			//noresultslink: "http://www.google.com/contacts/c/u/0/ui/ContactManager?titleBar=false",
            noresultslink: function(ev){
                //var supported_views = gadgets.views.getSupportedViews();
                //gadgets.views.requestNavigateTo(supported_views['canvas']);               
            },
			searchFunction: function(typedstr,callback){					
				filterContacts(typedstr,callback);
			},
			callback: function (obj, typedstr) { 
				var text = $.trim(obj.value);
				if (text.length>=3){              
					onSelectCallback(contactEntries[obj.seq]);
				}
			}
		}
	); 
};

function getGroupDurationHtml(entry,prefix)
{
	var duration = getExtendedProperty(entry,'duration');
	var html = '';
	html+='<span class="groupdurationlabel">Dur</span>';
	html+='<span class="groupdurationinput">';
	html+='<select name="groupduration" id="'+prefix+'_duration" class="duration" >';
	for(var i in durations){
		var selected=(duration && duration==durations[i])?'selected':'';
		html+='<option value="'+durations[i]+'" '+selected+' >'+getAsTimeFormat(durations[i])+'</option>';
	}
	html+='</select>';
	html+='</span>';
	return html;
}


function getGroupCalendarHtml(entry,prefix)
{
	var calendarid = getExtendedProperty(entry,'calendar'); 
	var html = '';
	html+='<div class="groupcalendar">';
	html+='<select name="groupcalendar" id="'+prefix+'_calendar">';
	for(var i in calendarEntries){
	    var selected=(calendarid && calendarid==calendarEntries[i].id.$t)?'selected':'';
		html+='<option value="'+calendarEntries[i].id.$t+'" '+selected+' >'+calendarEntries[i].title.$t+'</option>';
	}
	html+='</select>';
	html+='</div>';
	return html;
}

function getGroupPrice(entry,prefix)
{
	var price = getExtendedProperty(entry,'price') || ''; 
	var html = '';
	html+='<span class="grouppricelabel">R$</span>';
	html+='<span class="grouppriceinput">';
	html+='<input type="input" class="price" id="'+prefix+'_price" value="'+price+'" size="4" />';
	html+='</span>';
	return html;
}

function getGroupTitleHtml(entry,checkable,prefix)
{
	var checked = getExtendedProperty(entry,'checked') || ''; 
	var html = '';
	html+='<div class="groupname">';
	html+='<input type="hidden" id="'+prefix+'_group" value="'+entry.id.$t+'">';
	if (checkable){
		html+=' <input type="checkbox" class="groupchecked" id="'+prefix+'_checked" value="'+entry.id.$t+'" '+checked+'/>'+entry.title.$t+'<span id="'+prefix+'_status"></span>';
	}
	else{
		html+= '<div class="contactgroup">'+entry.title.$t+'</div>';
	}
	html+='</div>';
	return html;
}

function getGroupHtml(entry,prefix)
{
	var price = getExtendedProperty(entry,'price') || ''; 
	var html = '';
	html+='<div class="group">';	
	html+=getGroupTitleHtml(entry,true,prefix);
	html+=getGroupCalendarHtml(entry,prefix);
	html+=getGroupPrice(entry,prefix);
	html+=getGroupDurationHtml(entry,prefix);
	html+='</div>';
	return html;
}

function displayGroupsDiv()
{
	var html = '';
	html+='<div class="contacttoolbar">';
	html+='	<span id="btn6"><img width=16px height=16px title="save" style="cursor:pointer" onclick="onSaveGroups()" src="https://www.google.com/googlecalendar/icons/9.png"></span>';
	html+='	<span id="btn7"><a href="#" target="_blank" style="text-decoration: none;"><img width=16px height=16px title="Revert" src="http://www.google.com/googlecalendar/icons/12.png"></a></span>';
	html+='	<span id="btn8"></span>';
	html+='	<span id="btn9"></span>';
	html+='	<span id="btn0"></span>';
	html+='</div>';		
	var tabid = 1; // At this point it is not possible to use the selected index
	for(var i in groupEntries){
		var entry = groupEntries[i];
		var ctrlid = gdataid(entry.id.$t);
		var prefix = 'T'+tabid+'_'+ctrlid;
		html+=getGroupHtml(entry,prefix);
	}
	$('#groupbody').html(html);
}

function displaySearchDiv()
{
	curContact=null;
	var html = '<input id="contactsearch" name="contactsearch" type="text" class="contactsearch">';
	$('#contactbody').html(html);
	setupInputSearch("contactsearch", onContactSelected);
}

function onSaveGroups()
{
	var feedUri = "http://www.google.com/m8/feeds/groups/default/full";
	var updEntry = function(results){
		if (!results) {
			showWarning('Read_Error');
			return false;
		}
		for(var i in groupEntries){
			var entry = groupEntries[i];
			var tabid = 1; // At this point it is not possible to use the selected index
			var ctrlid = gdataid(entry.id.$t);				
			var prefix = 'T'+tabid+'_'+ctrlid;
			$('#'+prefix+'_status').html('<img width=16px height=16px style="cursor:wait" src="http://gaeinjail.googlecode.com/svn/www/gadgets/googlecalendar/loading.gif">');
			var checked = $('#'+prefix+'_checked').attr('checked'); 
			var calendar = $('#'+prefix+'_calendar').val();
			var duration = $('#'+prefix+'_duration').val();
			var price = $('#'+prefix+'_price').val();
			
			setExtendedProperty(entry,'checked',checked?'checked':'');
			setExtendedProperty(entry,'calendar',calendar);
			setExtendedProperty(entry,'duration',duration);
			setExtendedProperty(entry,'price',price);

			var onSuccess = function(result) {
				var upid = gdataid(result.entry.id.$t);
				var prefix = 'T'+tabid+'_'+upid;
				var ok = false;
				for(var j in groupEntries){
					if (groupEntries[j].id.$t==result.entry.id.$t){
						groupEntries[j]=result.entry;					
						$('#'+prefix+'_status').html('');
						//console.log('Group '+upid+' updated');
						ok = true;
						break;
					}
				}
				if (!ok){
					$('#'+prefix+'_status').html('<img width=16px title="updated with errors" height=16px src="http://www.google.com/googlecalendar/icons/12.png">');
					//console.log('Group '+upid+' updated with errors');				
				}
			}
			
			var onError = function(error) {
				//$('#'+_elID(entry,tabid,'status')).html('<img width=16px title="Group not updated" height=16px src="http://www.google.com/googlecalendar/icons/12.png">');
				//console.log('Group not updated');
			}
			
			entry.updateEntry(onSuccess,onError);
		}
		return true;
	};
	var gdataCallback = makeCallback(updEntry, arguments.callee);
	conService.getContactGroupFeed(feedUri, gdataCallback, gdataCallback);	
}

function onContactSelected(entry)
{
	if (!entry)
		return;

	curContact=entry;

	var tmp = curContact.id.$t.split('/');
	var contactid= tmp[tmp.length-1];
	var href='https://mail.google.com/mail/u/0/?tab=cm#contact/'+contactid;	
	
	var html = '';
	html+='<div class="contact">';
	// Name
	html+='<div class="contactname" ondblclick="displaySearchDiv()" style="cursor:pointer" >'+entry.title.$t+'</div>';	
	// Contct ToolBar
	html+='<div class="contacttoolbar">';
	html+='<span id="btn1"><img width=16px height=16px title="Click on a time slot to enable booking" src="https://www.google.com/googlecalendar/icons/8.png"></span>';
	html+='<span id="btn2"><a href="'+href+'" target="_blank" style="text-decoration: none;"><img width=16px height=16px title="Edit Contact" src="https://www.google.com/googlecalendar/icons/book.png"></a></span>';
	html+='<span id="btn3"></span>';
	html+='<span id="btn4"></span>';
	html+='<span id="btn5"></span>';
	html+='</div>';
	// Phones
	if (curContact['gd$phoneNumber']){
		var _htm = '';
		for(var i in curContact.gd$phoneNumber){
			var phonetype = getPhoneType(curContact.gd$phoneNumber[i].rel);
			var phonenumber = curContact.gd$phoneNumber[i].$t;
			if ($.trim(phonenumber)!==''){
				phonenumber=phonenumber.replace(/\"/g,'');
				_htm=_htm+'<div class="contactphone"><span class="phonetype">'+phonetype+'</span>'+phonenumber+'<span class="phonenumber">'+phonenumber+'</span></div>';
			}
		}
		html+=_htm;
	}
	// Group
	for(var i in curContact.gContact$groupMembershipInfo){
		var contactGroupId=curContact.gContact$groupMembershipInfo[i].href;		
		for(var j in groupEntries){
			if (groupEntries[j].id.$t==contactGroupId){
				var ctrlid = gdataid(curContact.id.$t);	
				var tabid = tabs.selectedTabIndex_;
				var prefix = 'T'+tabid+'_'+ctrlid;
				html+=getGroupTitleHtml(groupEntries[j],false,prefix);
				html+=getGroupCalendarHtml(groupEntries[j],prefix);
				html+=getGroupPrice(groupEntries[j],prefix);
				html+=getGroupDurationHtml(groupEntries[j],prefix);
				break;
			}
		}
	}
	html+= '</div>';
	$('#contactbody').html(html);
};

function onEvent(e) {
  if (!e){
	//displaySearchDiv();
	$('#btn1').html('<img width=16px height=16px title="Click on a time slot to enable booking" src="https://www.google.com/googlecalendar/icons/8.png">');
	return;
  }
  if (!e.id && e.startTime.hour && curContact){
    curEvent=e;
	$('#btn1').html('<img width=16px height=16px title="Book it" style="cursor:pointer" onclick="onCreateEvent()" src="https://www.google.com/googlecalendar/icons/9.png">');
	return;
  }
}

function onCreateEvent()
{
	$('#btn1').html('<img width=16px height=16px style="cursor:wait" src="http://gaeinjail.googlecode.com/svn/www/gadgets/googlecalendar/loading.gif">');
	var feedUri = 'https://www.google.com/calendar/feeds/default/private/full';
	var insEntry = function(results){
		if (!results) {
			showWarning('Read_Error');
			return false;
		}
		
		$('#btn1').fadeOut();
		// Extract values from the displayed html:
		var ctrlid = gdataid(curContact.id.$t);	
		var tabid = tabs.selectedTabIndex_;
		var prefix = 'T'+tabid+'_'+ctrlid;	
		
		//	Extended properties
		var calendar = $('#'+prefix+'_calendar').val();
		var duration = $('#'+prefix+'_duration').val();
		var group = $('#'+prefix+'_group').val();
		var price = $('#'+prefix+'_price').val();
		
		// Search for selected calendar
		var editUrl = null;
		for(var i in calendarEntries){
			if (calendarEntries[i].id.$t==calendar){
				for(var j in calendarEntries[i].link){
					if (calendarEntries[i].link[j].type=='application/atom+xml' && 
						calendarEntries[i].link[j].rel=="http://schemas.google.com/gCal/2005#eventFeed"
					){
						editUrl=calendarEntries[i].link[j].href;
						break;
					}
				}
			}
		}		
		
		// Create the new Event
		var sTime = curEvent.startTime;
		var eTime = getEndTime(sTime,duration);		
		var entry = new google.gdata.calendar.CalendarEventEntry({
			title: {
			  type: 'text', 
			  text: curContact.title.$t
			},
			content: {
			  type: 'text', 
			  text: ''
			},
			times: [{
				startTime: asDate(sTime),
				endTime: asDate(eTime)
			}]
		});
		setExtendedProperty(entry,'calendar',calendar);
		setExtendedProperty(entry,'duration',duration);
		setExtendedProperty(entry,'group',group);
		setExtendedProperty(entry,'price',price);
		setExtendedProperty(entry,'contact',curContact.id.$t);
		
		// Handler Functions
		var onSuccess = function(result) {
			google.calendar.refreshEvents(); // it is required or show event will fail
			var calid = (result.entry.id.$t.split('/')[5]).replace(/\%40/g,'@');
			var eveid = gdataid(result.entry.id.$t);
			var tmp = (eveid+' '+calid).substring(0,65);
			var gadgetid = Base64.encode(tmp);
			google.calendar.showEvent(gadgetid);		
		}
		
		var onError = function(error) {
			$('#btn1').html('<img width=16px height=16px title="update error" src="http://gaeinjail.googlecode.com/svn/www/gadgets/googlecalendar/12.gif">');
		}
		
		calService.insertEntry(editUrl, entry, onSuccess,onError);
		return true;
	};
	var gdataCallback = makeCallback(insEntry, arguments.callee);
	var query = new google.gdata.calendar.CalendarEventQuery(feedUri);		
	query.setMaxResults(1);
	calService.getEventsFeed(query, gdataCallback, gdataCallback);
}

function asIso8601(et)
{
	//"2011-06-07T09:00:00.000-03:00"
	var dtFormated=et.year.toString()+'-'+et.month.toString()+'-'+et.date.toString()+'T'+et.hour.toString()+':'+et.minute.toString()+':'+et.second.toString()+'.000-03:00'
	return dtFormated;
}

function asDate(et)
{
	return new Date(et.year,et.month-1,et.date,et.hour,et.minute,et.second,0);
}


function fetchContacts(group,onFinish)
{	
	$('#contactbody').html('loading contacts');
	var feedUri = 'http://www.google.com/m8/feeds/contacts/default/full';	
	var load = function(results){
		if (!results) {
			showWarning('Read_Error');
			return false;
		}
		contactEntries=contactEntries.concat(results.feed.entry);
		if (onFinish && (typeof onFinish)=='function'){
			onFinish();
		}
		return true;		
	};	
	var query = new google.gdata.contacts.ContactQuery(feedUri);		
	query.setMaxResults(400);
	query.setGroup(group.id.$t);
	var gdataCallback = makeCallback(load, arguments.callee);
	conService.getContactFeed(query, gdataCallback, gdataCallback);	
};	

function fetchGroups(){
	$('#contactbody').html('loading groups');
	var feedUri = "http://www.google.com/m8/feeds/groups/default/full";	
	var load = function(results){
		if (!results) {
			showWarning('Read_Error');
			return false;
		}
		groupEntries=[];
		contactEntries=[];
		for(var i=0;i<results.feed.entry.length;i++){
			if (!results.feed.entry[i]['gContact$systemGroup']){
				groupEntries.push(results.feed.entry[i]);
			}
		}
		for(var j=0;j<groupEntries.length;j++){
			if (j==groupEntries.length-1){
				fetchContacts(groupEntries[j],function(){
					displaySearchDiv();
					displayGroupsDiv();
				});
			}
			else{
				fetchContacts(groupEntries[j]);
			}
		}	
		return true;
	}
	var query = new google.gdata.contacts.ContactQuery(feedUri);		
	query.setMaxResults(100);
	var gdataCallback = makeCallback(load, arguments.callee);
	conService.getContactGroupFeed(query, gdataCallback, gdataCallback);		
}

function fetchCalendars(){
	$('#contactbody').html('loading calendars');
	var feedUri='http://www.google.com/calendar/feeds/default/allcalendars/full';
	var load = function(results){
		if (!results) {
			showWarning('Read_Error');
			return false;
		}
		calendarEntries = [];
		for (var i = 0; i < results.feed.entry.length; i++) {
		    var entry = results.feed.entry[i];
			var acl = (entry.gCal$accesslevel && entry.gCal$accesslevel.value)?entry.gCal$accesslevel.value:'owner';
			if (acl=='owner'||acl=='root'||acl=='editor'){
				calendarEntries.push(entry);
			}
		};
        fetchGroups();
    	return true;
	}
	var gdataCallback = makeCallback(load, arguments.callee);
	calService.getEventsFeed(feedUri, gdataCallback);		
}


function show(html) {
  _gel('contactbody').innerHTML = html;
  //gadgets.window.adjustHeight();
  gadgets.window.adjustHeight(400);
}

function showWarning(text) {
  if (text) {
    show('<div style="margin-left:5px;font-size:90%;color:#666">' + gadgets.util.escapeString(text) + '</div>');
  } else {
    _gel('contactbody').innerHTML = '';
    //gadgets.window.adjustHeight(1);
	gadgets.window.adjustHeight(400);
  }
}

function init(moduleid){

	initGData();
	google.calendar.read.subscribeToEvents(onEvent);
		
	tabs = new gadgets.TabSet(moduleid, "Contact");
	
	tabs.addTab("Contact", {contentContainer: document.getElementById("tabContact"), index:0});
	tabs.addTab("Groups", {contentContainer: document.getElementById("tabGroups"), index:1});
	tabs.addTab("Docs", {contentContainer: document.getElementById("tabDocs"), index:2});
	
	fetchCalendars();
}
